package com.xxlie.auth.service.impl;

import com.xxlie.auth.service.MenuService;
import com.xxlie.auth.common.UserLoginContext;
import com.xxlie.auth.domain.Role;
import com.xxlie.auth.domain.Menu;
import com.xxlie.auth.domain.User;
import com.xxlie.auth.repository.MenuRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 *
 *
 * @author xxlie.com
 * @since 2017/7/30
 */
@Service
@Transactional(readOnly = true)
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuRepository menuRepository;

    @Override
    public Menu findOne(Long id) {
        return menuRepository.findOne(id);
    }

    @Override
    public List<Menu> getMenuList(HttpServletRequest request, HttpServletResponse response) {

        User currentUser = UserLoginContext.getCurrentUser();
//        if (currentUser.isAdmin()) {
//            return menuRepository.findAllList();
//        } else {
        return menuRepository.findByUserId(currentUser.getId());
//        }

    }

    @Override
    public List<Menu> findByRoot() {
        Sort sort = new Sort(Sort.Direction.ASC, "sort");
        return menuRepository.findAll(new Specification<Menu>() {

            @Override
            public Predicate toPredicate(Root<Menu> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) {
                List<Predicate> predicates = new ArrayList<>();
                predicates.add(builder.isNull(root.get("parent")));
                predicates.add(builder.like(root.get("delFlag"), Role.DEL_FLAG_NORMAL));
                Predicate[] predicatesArray = new Predicate[predicates.size()];
                predicates.toArray(predicatesArray);
                return builder.and(predicatesArray);
            }

        }, sort);
    }

    @Transactional
    @Override
    public void save(Menu menu) {

        if (menu.getParent() == null || menu.getParent().getId() == null) {
            menu.setParent(null);
        }
        menuRepository.save(menu);

        String oldParentIds = menu.getParentIds(); // 获取修改前的parentIds，用于更新子节点的parentIds
        // 更新子节点 parentIds
        List<Menu> list = menuRepository.findByParentIdsLike("%," + menu.getId() + ",%");
        for (Menu e : list) {
            e.setParentIds(e.getParentIds().replace(oldParentIds, menu.getParentIds()));
        }
        menuRepository.save(list);

    }

    @Transactional
    @Override
    public void delete(Long id) {
        menuRepository.deleteById(id, "%," + id + ",%");
    }

    @Override
    public List<Menu> findAll() {
        return menuRepository.findAll();
    }
}
